<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>C Assembly</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
  var popup = document.getElementById(material_id);
  popup.classList.toggle("show");
}
</script>

<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Extracts-Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'C Assembly' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../intern.html">Inter Modules</a></li><li><a href="index.html">final</a></li><li><a href="index.html#5">Chapter 5: C</a></li><li><b>C Assembly</b></li></ul></div>
<p class="purpose">The problem of assembly language.</p>

<ul class="toc"><li><a href="5-cas.html#SP1">&#167;1. General implementation</a></li><li><a href="5-cas.html#SP8">&#167;8. call</a></li><li><a href="5-cas.html#SP9">&#167;9. copy</a></li><li><a href="5-cas.html#SP10">&#167;10. aload, aloads, aloadb</a></li><li><a href="5-cas.html#SP11">&#167;11. ushiftr, shiftl</a></li><li><a href="5-cas.html#SP12">&#167;12. jeq, jleu, jnz, jz</a></li><li><a href="5-cas.html#SP13">&#167;13. nop, quit, verify</a></li><li><a href="5-cas.html#SP14">&#167;14. restoreundo, saveundo, hasundo, discardundo</a></li><li><a href="5-cas.html#SP15">&#167;15. restart, restore, save</a></li><li><a href="5-cas.html#SP16">&#167;16. streamchar, streamnum, streamunichar</a></li><li><a href="5-cas.html#SP17">&#167;17. binarysearch</a></li><li><a href="5-cas.html#SP18">&#167;18. mcopy, mzero, malloc, mfree</a></li><li><a href="5-cas.html#SP19">&#167;19. random, setrandom</a></li><li><a href="5-cas.html#SP20">&#167;20. setiosys</a></li><li><a href="5-cas.html#SP21">&#167;21. gestalt</a></li></ul><hr class="tocbar">

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. General implementation.</b>This section does just one thing: compiles invocations of assembly-language
opcodes.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CAssembly::initialise</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">CAssembly::initialise</span></span>:<br/>Final C - <a href="5-fnc.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generator</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gtr</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">METHOD_ADD</span><span class="plain-syntax">(</span><span class="identifier-syntax">gtr</span><span class="plain-syntax">, </span><span class="constant-syntax">INVOKE_OPCODE_MTID</span><span class="plain-syntax">, </span><a href="5-cas.html#SP6" class="function-link"><span class="function-syntax">CAssembly::invoke_opcode</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">METHOD_ADD</span><span class="plain-syntax">(</span><span class="identifier-syntax">gtr</span><span class="plain-syntax">, </span><span class="constant-syntax">ASSEMBLY_MARKER_MTID</span><span class="plain-syntax">, </span><a href="5-cas.html#SP7" class="function-link"><span class="function-syntax">CAssembly::assembly_marker</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">C_generation_assembly_data</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">dictionary</span><span class="plain-syntax"> *</span><span class="identifier-syntax">opcodes_used</span><span class="plain-syntax">;</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">C_generation_assembly_data</span><span class="plain-syntax">;</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CAssembly::initialise_data</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">CAssembly::initialise_data</span></span>:<br/>Final C - <a href="5-fnc.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">C_GEN_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">asmdata</span><span class="plain-syntax">.</span><span class="element-syntax">opcodes_used</span><span class="plain-syntax">) = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CAssembly::begin</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">CAssembly::begin</span></span>:<br/>Final C - <a href="5-fnc.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP1" class="function-link"><span class="function-syntax">CAssembly::initialise_data</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CAssembly::end</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">CAssembly::end</span></span>:<br/>Final C - <a href="5-fnc.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure C_generation_assembly_data is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>Inter is for the most part fully specified and cross-platform, but assembly
language is the big hole in that. It is legal for Inter code to contain almost
anything which purports to be assembly language. For example, the following
code will successfully build as part of an Inter kit:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    [ </span><span class="identifier-syntax">Peculiar</span><span class="plain-syntax"> </span><span class="identifier-syntax">x</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        @</span><span class="identifier-syntax">bandersnatch</span><span class="plain-syntax"> </span><span class="identifier-syntax">x</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    ];</span>
</pre>
<p class="commentary">Kit code, and also material included in <span class="extract"><span class="extract-syntax">(-</span></span> and <span class="extract"><span class="extract-syntax">-)</span></span> brackets in I7 source text,
can claim to use assembly language opcodes with any names it likes. No checking
is done that these are "real" opcodes. (Spoilers: <span class="extract"><span class="extract-syntax">@bandersnatch</span></span> is not.)
</p>

<p class="commentary">The point of this is that different final targets support different sets of
assembly language. This was always true for Inform 6 code (after around 2000,
anyway), because the Z and Glulx virtual machines had different assembly
languages: <span class="extract"><span class="extract-syntax">@split_window</span></span> exists for Z but not Glulx, <span class="extract"><span class="extract-syntax">@atan</span></span> exists for
Glulx but not Z, for example.
</p>

<p class="commentary">So each different final generator needs to make its own decision about what
assembly language opcodes to provide, and what they will do. In theory, we could
make an entirely new assembly language for C. But in practice that would just
make the standard Inform kits, such as BasicInformKit, impossible to support
on C, because those kits make quite heavy use of opcodes from Z/Glulx.
</p>

<p class="commentary">We will instead:
</p>

<ul class="items"><li>(1) Emulate exactly that subset of the Glulx assembly language which is used
by the standard Inform kits, and
</li><li>(2) Allow any other opcodes to be externally defined by the user.
</li></ul>
<p class="commentary">In this way, we obtain both compatibility with the Inform kits, enabling us to
compile works of IF to C, and also extensibility.
</p>

<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>Each different opcode we see will be matched up to a <a href="5-cas.html#SP3" class="internal">C_supported_opcode</a>
giving it some metadata: we will gather these into a dictionary so that names
of opcodes can quickly be resolved to their metadata structures.
</p>

<p class="commentary">That dictionary will begin with (1) about 60 standard supported opcodes, but
then may pick up (2) a few others such as <span class="extract"><span class="extract-syntax">@bandersnatch</span></span>, if kits do something
non-standard.
</p>

<p class="commentary">So now we define some very minimal metadata on our opcodes. Each opcode will,
when used, be followed by a number of operands, which we number from 1:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    @</span><span class="identifier-syntax">fmod</span><span class="plain-syntax"> </span><span class="identifier-syntax">a</span><span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> </span><span class="identifier-syntax">rem</span><span class="plain-syntax"> </span><span class="identifier-syntax">quot</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="comment-syntax">    1 2 3   4</span>
</pre>
<p class="commentary">This opcode, which performs floating-point division with remainder, reads in
operands 1 and 2, and writes results out to operands 3 and 4. In the following,
<span class="extract"><span class="extract-syntax">store_this_operand[3]</span></span> and <span class="extract"><span class="extract-syntax">store_this_operand[4]</span></span> would be <span class="extract"><span class="extract-syntax">TRUE</span></span>, while
<span class="extract"><span class="extract-syntax">store_this_operand[1]</span></span> and <span class="extract"><span class="extract-syntax">store_this_operand[2]</span></span> would be <span class="extract"><span class="extract-syntax">FALSE</span></span>. (In fact,
this is an outlier, because it is the only opcode we support which has more than
one store operand. But in principle we could have many.)
</p>

<p class="commentary">Glulx assembly language also allows variable numbers of arguments to some opcodes,
or "varargs". For example:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    @</span><span class="identifier-syntax">glk</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax"> </span><span class="identifier-syntax">_vararg_count</span><span class="plain-syntax"> </span><span class="identifier-syntax">ret</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="comment-syntax">   1 2             3</span>
</pre>
<p class="commentary">Here operand 3 is a store, and operands 1 and 2 are read in. But operand 2 is
special in that it is a count of additional operands which are found on the
stack rather than in the body of the instruction. For example,
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    @</span><span class="identifier-syntax">glk</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax"> </span><span class="constant-syntax">6</span><span class="plain-syntax"> </span><span class="identifier-syntax">ret</span><span class="plain-syntax">;</span>
</pre>
<p class="commentary">would provide <span class="extract"><span class="extract-syntax">@glk</span></span> with seven operands to read in: the one in the instruction
itself, <span class="extract"><span class="extract-syntax">4</span></span>, and then the top 6 items on the stack.
</p>

<p class="commentary">Because of this, an operand holding a variable-argument count is special. There
can be at most one for any opcode; <span class="extract"><span class="extract-syntax">vararg_operand</span></span> is -1 if there isn't one,
but for <span class="extract"><span class="extract-syntax">@glk</span></span>, <span class="extract"><span class="extract-syntax">vararg_operand</span></span> would be 2.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">C_supported_opcode</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">; </span><span class="comment-syntax"> including the opening </span><span class="extract"><span class="extract-syntax">@</span></span><span class="comment-syntax"> character</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">store_this_operand</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_OPERANDS_IN_INTER_ASSEMBLY</span><span class="plain-syntax">];</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">vararg_operand</span><span class="plain-syntax">; </span><span class="comment-syntax"> position of </span><span class="extract"><span class="extract-syntax">_vararg_count</span></span><span class="comment-syntax"> operand, or -1 if none</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">speculative</span><span class="plain-syntax">; </span><span class="comment-syntax"> i.e., not part of the standard supported set</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">C_supported_opcode</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure C_supported_opcode is accessed in 5/com and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>On creation, a <a href="5-cas.html#SP3" class="internal">C_supported_opcode</a> is automatically added to the dictionary:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">C_supported_opcode</span><span class="plain-syntax"> *</span><span class="function-syntax">CAssembly::new_opcode</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">CAssembly::new_opcode</span></span>:<br/><a href="5-cas.html#SP5_1">&#167;5.1</a>, <a href="5-cas.html#SP5_2">&#167;5.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">s1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">s2</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">va</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">C_supported_opcode</span><span class="plain-syntax"> *</span><span class="identifier-syntax">opc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">C_supported_opcode</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">opc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">speculative</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">opc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">MAX_OPERANDS_IN_INTER_ASSEMBLY</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="identifier-syntax">opc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">store_this_operand</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">s1</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">opc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">store_this_operand</span><span class="plain-syntax">[</span><span class="identifier-syntax">s1</span><span class="plain-syntax">] = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">s2</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">opc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">store_this_operand</span><span class="plain-syntax">[</span><span class="identifier-syntax">s2</span><span class="plain-syntax">] = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">opc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">vararg_operand</span><span class="plain-syntax"> = </span><span class="identifier-syntax">va</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Dictionaries::create</span><span class="plain-syntax">(</span><span class="identifier-syntax">C_GEN_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">asmdata</span><span class="plain-syntax">.</span><span class="element-syntax">opcodes_used</span><span class="plain-syntax">), </span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Dictionaries::write_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">C_GEN_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">asmdata</span><span class="plain-syntax">.</span><span class="element-syntax">opcodes_used</span><span class="plain-syntax">), </span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="identifier-syntax">opc</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">opc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>When the generator encounters an opcode called <span class="extract"><span class="extract-syntax">name</span></span> which seems to be used
with <span class="extract"><span class="extract-syntax">operand_count</span></span> operands, it calls the following function to find the
corresponding metadata. Note that this always returns a valid <a href="5-cas.html#SP3" class="internal">C_supported_opcode</a>,
because even if a completely unexpected name is encountered, the above
mechanism will just create a meaning for it.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">C_supported_opcode</span><span class="plain-syntax"> *</span><span class="function-syntax">CAssembly::find_opcode</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">CAssembly::find_opcode</span></span>:<br/><a href="5-cas.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">operand_count</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C_GEN_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">asmdata</span><span class="plain-syntax">.</span><span class="element-syntax">opcodes_used</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">C_GEN_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">asmdata</span><span class="plain-syntax">.</span><span class="element-syntax">opcodes_used</span><span class="plain-syntax">) = </span><span class="identifier-syntax">Dictionaries::new</span><span class="plain-syntax">(256, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="5-cas.html#SP5_1" class="named-paragraph-link"><span class="named-paragraph">Stock with the basics</span><span class="named-paragraph-number">5.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">C_supported_opcode</span><span class="plain-syntax"> *</span><span class="identifier-syntax">opc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Dictionaries::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">C_GEN_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">asmdata</span><span class="plain-syntax">.</span><span class="element-syntax">opcodes_used</span><span class="plain-syntax">), </span><span class="identifier-syntax">name</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">opc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Dictionaries::read_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">C_GEN_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">asmdata</span><span class="plain-syntax">.</span><span class="element-syntax">opcodes_used</span><span class="plain-syntax">), </span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="5-cas.html#SP5_2" class="named-paragraph-link"><span class="named-paragraph">Add a speculative new opcode to the dictionary</span><span class="named-paragraph-number">5.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">opc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5_1" class="paragraph-anchor"></a><b>&#167;5.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Stock with the basics</span><span class="named-paragraph-number">5.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@acos"</span><span class="plain-syntax">,             </span><span class="constant-syntax">2</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@add"</span><span class="plain-syntax">,              </span><span class="constant-syntax">3</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@aload"</span><span class="plain-syntax">,            </span><span class="constant-syntax">3</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@aloadb"</span><span class="plain-syntax">,           </span><span class="constant-syntax">3</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@aloads"</span><span class="plain-syntax">,           </span><span class="constant-syntax">3</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@asin"</span><span class="plain-syntax">,             </span><span class="constant-syntax">2</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@atan"</span><span class="plain-syntax">,             </span><span class="constant-syntax">2</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@binarysearch"</span><span class="plain-syntax">,     </span><span class="constant-syntax">8</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@call"</span><span class="plain-syntax">,             </span><span class="constant-syntax">3</span><span class="plain-syntax">, -1,  </span><span class="constant-syntax">2</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@ceil"</span><span class="plain-syntax">,             </span><span class="constant-syntax">2</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@copy"</span><span class="plain-syntax">,             </span><span class="constant-syntax">2</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@cos"</span><span class="plain-syntax">,              </span><span class="constant-syntax">2</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@div"</span><span class="plain-syntax">,              </span><span class="constant-syntax">3</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@exp"</span><span class="plain-syntax">,              </span><span class="constant-syntax">2</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@fadd"</span><span class="plain-syntax">,             </span><span class="constant-syntax">3</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@fdiv"</span><span class="plain-syntax">,             </span><span class="constant-syntax">3</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@floor"</span><span class="plain-syntax">,            </span><span class="constant-syntax">2</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@fmod"</span><span class="plain-syntax">,             </span><span class="constant-syntax">3</span><span class="plain-syntax">,  </span><span class="constant-syntax">4</span><span class="plain-syntax">, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@fmul"</span><span class="plain-syntax">,             </span><span class="constant-syntax">3</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@fsub"</span><span class="plain-syntax">,             </span><span class="constant-syntax">3</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@ftonumn"</span><span class="plain-syntax">,          </span><span class="constant-syntax">2</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@ftonumz"</span><span class="plain-syntax">,          </span><span class="constant-syntax">2</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@gestalt"</span><span class="plain-syntax">,          </span><span class="constant-syntax">3</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@glk"</span><span class="plain-syntax">,              </span><span class="constant-syntax">3</span><span class="plain-syntax">, -1,  </span><span class="constant-syntax">2</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@hasundo"</span><span class="plain-syntax">,          </span><span class="constant-syntax">1</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@jeq"</span><span class="plain-syntax">,             -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@jfeq"</span><span class="plain-syntax">,            -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@jfge"</span><span class="plain-syntax">,            -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@jflt"</span><span class="plain-syntax">,            -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@jisinf"</span><span class="plain-syntax">,          -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@jisnan"</span><span class="plain-syntax">,          -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@jleu"</span><span class="plain-syntax">,            -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@jnz"</span><span class="plain-syntax">,             -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@jz"</span><span class="plain-syntax">,              -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@log"</span><span class="plain-syntax">,              </span><span class="constant-syntax">2</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@malloc"</span><span class="plain-syntax">,          -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@mcopy"</span><span class="plain-syntax">,           -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@mzero"</span><span class="plain-syntax">,           -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@mfree"</span><span class="plain-syntax">,           -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@mod"</span><span class="plain-syntax">,              </span><span class="constant-syntax">3</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@mul"</span><span class="plain-syntax">,              </span><span class="constant-syntax">3</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@neg"</span><span class="plain-syntax">,              </span><span class="constant-syntax">2</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@nop"</span><span class="plain-syntax">,             -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@numtof"</span><span class="plain-syntax">,           </span><span class="constant-syntax">2</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@pow"</span><span class="plain-syntax">,              </span><span class="constant-syntax">3</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@quit"</span><span class="plain-syntax">,            -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@random"</span><span class="plain-syntax">,           </span><span class="constant-syntax">2</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@restart"</span><span class="plain-syntax">,         -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@restore"</span><span class="plain-syntax">,          </span><span class="constant-syntax">2</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@restoreundo"</span><span class="plain-syntax">,      </span><span class="constant-syntax">1</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@return"</span><span class="plain-syntax">,          -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@save"</span><span class="plain-syntax">,             </span><span class="constant-syntax">2</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@saveundo"</span><span class="plain-syntax">,         </span><span class="constant-syntax">1</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@setiosys"</span><span class="plain-syntax">,        -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@setrandom"</span><span class="plain-syntax">,       -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@shiftl"</span><span class="plain-syntax">,           </span><span class="constant-syntax">3</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@sin"</span><span class="plain-syntax">,              </span><span class="constant-syntax">2</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@sqrt"</span><span class="plain-syntax">,             </span><span class="constant-syntax">2</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@streamchar"</span><span class="plain-syntax">,      -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@streamnum"</span><span class="plain-syntax">,       -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@streamunichar"</span><span class="plain-syntax">,   -1, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@sub"</span><span class="plain-syntax">,              </span><span class="constant-syntax">3</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@tan"</span><span class="plain-syntax">,              </span><span class="constant-syntax">2</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@ushiftr"</span><span class="plain-syntax">,          </span><span class="constant-syntax">3</span><span class="plain-syntax">, -1, -1);</span>
<span class="plain-syntax">    </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@verify"</span><span class="plain-syntax">,           </span><span class="constant-syntax">1</span><span class="plain-syntax">, -1, -1);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cas.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_2" class="paragraph-anchor"></a><b>&#167;5.2. </b>Speculative opcodes cannot store and cannot have varargs. Also, since they
are not part of our supported set, there's no code here to implement them.
Instead we predeclare a function and simply assume that the user will have
written this function somewhere and linked it to us. For example, we might
predeclare this:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="identifier-syntax">i7_opcode_bandersnatch</span><span class="plain-syntax">(</span><span class="identifier-syntax">i7process_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">proc</span><span class="plain-syntax">, </span><span class="identifier-syntax">i7word_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">v1</span><span class="plain-syntax">);</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Add a speculative new opcode to the dictionary</span><span class="named-paragraph-number">5.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">opc</span><span class="plain-syntax"> = </span><a href="5-cas.html#SP4" class="function-link"><span class="function-syntax">CAssembly::new_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">, -1, -1, -1);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">opc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">speculative</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">segmentation_pos</span><span class="plain-syntax"> </span><span class="identifier-syntax">saved</span><span class="plain-syntax"> = </span><a href="2-cg.html#SP12" class="function-link"><span class="function-syntax">CodeGen::select</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="constant-syntax">c_predeclarations_I7CGS</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OUT</span><span class="plain-syntax"> = </span><a href="2-cg.html#SP14" class="function-link"><span class="function-syntax">CodeGen::current</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"void "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="5-cnm.html#SP4" class="function-link"><span class="function-syntax">CNamespace::mangle_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"(i7process_t *proc"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=1; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;=</span><span class="identifier-syntax">operand_count</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", i7word_t v%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">");\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-cg.html#SP12" class="function-link"><span class="function-syntax">CodeGen::deselect</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">saved</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cas.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>We finally have enough infrastructure to invoke a general assembly-language
instruction found in our Inter.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CAssembly::invoke_opcode</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">CAssembly::invoke_opcode</span></span>:<br/><a href="5-cas.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generator</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gtr</span><span class="plain-syntax">, </span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">opcode</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">operand_count</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> **</span><span class="identifier-syntax">operands</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">label</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">label_sense</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">C_supported_opcode</span><span class="plain-syntax"> *</span><span class="identifier-syntax">opc</span><span class="plain-syntax"> = </span><a href="5-cas.html#SP5" class="function-link"><span class="function-syntax">CAssembly::find_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">opcode</span><span class="plain-syntax">, </span><span class="identifier-syntax">operand_count</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OUT</span><span class="plain-syntax"> = </span><a href="2-cg.html#SP14" class="function-link"><span class="function-syntax">CodeGen::current</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">label_sense</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-cas.html#SP6_1" class="named-paragraph-link"><span class="named-paragraph">Begin a branch instruction</span><span class="named-paragraph-number">6.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">push_store</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_OPERANDS_IN_INTER_ASSEMBLY</span><span class="plain-syntax">];</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">MAX_OPERANDS_IN_INTER_ASSEMBLY</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="identifier-syntax">push_store</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="5-cas.html#SP6_3" class="named-paragraph-link"><span class="named-paragraph">Generate a function call</span><span class="named-paragraph-number">6.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">label_sense</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-cas.html#SP6_2" class="named-paragraph-link"><span class="named-paragraph">End a branch instruction</span><span class="named-paragraph-number">6.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="5-cas.html#SP6_4" class="named-paragraph-link"><span class="named-paragraph">Push any stored results which need to end up on the stack</span><span class="named-paragraph-number">6.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">";\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6_1" class="paragraph-anchor"></a><b>&#167;6.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Begin a branch instruction</span><span class="named-paragraph-number">6.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"if ("</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cas.html#SP6">&#167;6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6_2" class="paragraph-anchor"></a><b>&#167;6.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">End a branch instruction</span><span class="named-paragraph-number">6.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">label_sense</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" == FALSE"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">") goto "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">label</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no branch label"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-vnl.html#SP4" class="function-link"><span class="function-syntax">Vanilla::node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">label</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cas.html#SP6">&#167;6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6_3" class="paragraph-anchor"></a><b>&#167;6.3. </b>Each instruction becomes a function call to the function implementing the
opcode in question, except that <span class="extract"><span class="extract-syntax">@return</span></span> becomes the C statement <span class="extract"><span class="extract-syntax">return</span></span>.
If the opcode has N operands then the function has N+1 arguments, since the
first is always the process pointer.
</p>

<p class="commentary">It may seem to compile slow code if we turn instructions into function calls, but
</p>

<ul class="items"><li>(a) assembly is not used very much in Inter code, and then not for time-sensitive
operations, and
</li><li>(b) the C compiler receiving the code we generate will almost certainly perform
inline optimisation to remove most of these calls anyway.
</li></ul>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Generate a function call</span><span class="named-paragraph-number">6.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">opcode</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"@return"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"return ("</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><a href="5-cnm.html#SP4" class="function-link"><span class="function-syntax">CNamespace::mangle_opcode</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">opcode</span><span class="plain-syntax">); </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"(proc"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">operand_count</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">operand</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="identifier-syntax">operand</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">operand_count</span><span class="plain-syntax">; </span><span class="identifier-syntax">operand</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">operand</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">O</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><a href="2-cg.html#SP13" class="function-link"><span class="function-syntax">CodeGen::select_temporary</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">O</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-vnl.html#SP4" class="function-link"><span class="function-syntax">Vanilla::node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">operands</span><span class="plain-syntax">[</span><span class="identifier-syntax">operand</span><span class="plain-syntax">-1]);</span>
<span class="plain-syntax">        </span><a href="2-cg.html#SP13" class="function-link"><span class="function-syntax">CodeGen::deselect_temporary</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">opc</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">store_this_operand</span><span class="plain-syntax">[</span><span class="identifier-syntax">operand</span><span class="plain-syntax">]) </span><span class="named-paragraph-container code-font"><a href="5-cas.html#SP6_3_2" class="named-paragraph-link"><span class="named-paragraph">Generate a store operand</span><span class="named-paragraph-number">6.3.2</span></a></span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-cas.html#SP6_3_1" class="named-paragraph-link"><span class="named-paragraph">Generate a regular operand</span><span class="named-paragraph-number">6.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">O</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cas.html#SP6">&#167;6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6_3_1" class="paragraph-anchor"></a><b>&#167;6.3.1. </b>The argument for a regular operand will have type <span class="extract"><span class="extract-syntax">i7word_t</span></span>, so we have to
compile something of that type here.
</p>

<p class="commentary">The special operand notation <span class="extract"><span class="extract-syntax">sp</span></span> is a pseudo-variable meaning "the top of the
stack", so if we see that then we compile that to a pull: note that <span class="extract"><span class="extract-syntax">i7_pull</span></span>
returns an <span class="extract"><span class="extract-syntax">i7word_t</span></span>.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Generate a regular operand</span><span class="named-paragraph-number">6.3.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">O</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"sp"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"i7_pull(proc)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">O</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cas.html#SP6_3">&#167;6.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6_3_2" class="paragraph-anchor"></a><b>&#167;6.3.2. </b>The argument for a store operand will have type <span class="extract"><span class="extract-syntax">i7word_t *</span></span>, so now we have
to make a pointer.
</p>

<p class="commentary">Again, <span class="extract"><span class="extract-syntax">sp</span></span> is a pseudo-variable meaning "the top of the stack", but this time
we have to push, not pull, and that's something we can't do until the function
has returned &mdash; the function will create the value we need to push. We get
around this by compiling a pointer to some temporary memory.
</p>

<p class="commentary">Finally, assembly also allows <span class="extract"><span class="extract-syntax">0</span></span> as a special value for a store operand, and
this means "throw the value away". We don't want to incur a C compiler warning
by attempting to write <span class="extract"><span class="extract-syntax">0</span></span> in a pointer context, so we pass it as <span class="extract"><span class="extract-syntax">NULL</span></span> instead.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Generate a store operand</span><span class="named-paragraph-number">6.3.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">O</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"sp"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&amp;(proc-&gt;state.tmp[%d])"</span><span class="plain-syntax">, </span><span class="identifier-syntax">operand</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">push_store</span><span class="plain-syntax">[</span><span class="identifier-syntax">operand</span><span class="plain-syntax">] = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">O</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"0"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"NULL"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&amp;%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">O</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cas.html#SP6_3">&#167;6.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6_4" class="paragraph-anchor"></a><b>&#167;6.4. </b>That may leave a few stored results stranded in temporary workspace, so:
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Push any stored results which need to end up on the stack</span><span class="named-paragraph-number">6.4</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">operand</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="identifier-syntax">operand</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">operand_count</span><span class="plain-syntax">; </span><span class="identifier-syntax">operand</span><span class="plain-syntax">++)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">push_store</span><span class="plain-syntax">[</span><span class="identifier-syntax">operand</span><span class="plain-syntax">])</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"; i7_push(proc, proc-&gt;state.tmp[%d])"</span><span class="plain-syntax">, </span><span class="identifier-syntax">operand</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-cas.html#SP6">&#167;6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </b>And where does the special operand <span class="extract"><span class="extract-syntax">sp</span></span> come from? From here:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CAssembly::assembly_marker</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">CAssembly::assembly_marker</span></span>:<br/><a href="5-cas.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generator</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gtr</span><span class="plain-syntax">, </span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax"> </span><span class="identifier-syntax">marker</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OUT</span><span class="plain-syntax"> = </span><a href="2-cg.html#SP14" class="function-link"><span class="function-syntax">CodeGen::current</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">marker</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">ASM_SP_ASMMARKER:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"sp"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">default:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">STDERR</span><span class="plain-syntax">, </span><span class="string-syntax">"Unsupported assembly marker is '%d'\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">marker</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"unsupported assembly marker in C"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. call.</b>That does everything except to implement the standard set of opcodes, which
must be done with about 60 functions in the C library.
</p>

<p class="commentary">This is not the place to specify what Glulx opcodes do. See Andrew Plotkin's
<a href="https://www.eblong.com/zarf/glulx" class="external">documentation on the Glulx virtual machine</a>.
</p>

<p class="commentary">Most of the opcodes we support are defined below, but see also <a href="5-cim.html" class="internal">C Input-Output Model</a>
for <span class="extract"><span class="extract-syntax">@glk</span></span>, and see <a href="5-car.html" class="internal">C Arithmetic</a> for the plethora of mathematical operations
such as <span class="extract"><span class="extract-syntax">@fmul</span></span>.
</p>

<p class="commentary">To begin, here is a <span class="extract"><span class="extract-syntax">@call</span></span>, which performs a function call to a perhaps computed
address:
</p>

<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_call</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">fn_ref</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">varargc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.h.</li></ul>
<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_call</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">fn_ref</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">varargc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">args</span><span class="Extracts-plain-syntax">[10]; </span><span class="Extracts-identifier-syntax">for</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">int</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">=0; </span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">&lt;10; </span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">++) </span><span class="Extracts-identifier-syntax">args</span><span class="Extracts-plain-syntax">[</span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">] = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">for</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">int</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">=0; </span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">&lt;</span><span class="Extracts-identifier-syntax">varargc</span><span class="Extracts-plain-syntax">; </span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">++) </span><span class="Extracts-identifier-syntax">args</span><span class="Extracts-plain-syntax">[</span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">] = </span><span class="Extracts-identifier-syntax">i7_pull</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">rv</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">i7_gen_call</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">fn_ref</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">args</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">varargc</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">) *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">rv</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.c.</li></ul>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. copy.</b>Though it doesn't look it, this is one of the main ways Glulx assembly language
programs push or pull to the stack &mdash; <span class="extract"><span class="Extracts-extract-syntax">@copy sp x</span></span> pulls the stack to <span class="extract"><span class="Extracts-extract-syntax">x</span></span>;
<span class="extract"><span class="Extracts-extract-syntax">@copy sp 0</span></span> pops the stack; <span class="extract"><span class="Extracts-extract-syntax">@copy x sp</span></span> pushes <span class="extract"><span class="Extracts-extract-syntax">x</span></span> to the stack. But all of
that is handled by the general mechanism above.
</p>

<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_copy</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.h.</li></ul>
<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_copy</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">) *</span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.c.</li></ul>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. aload, aloads, aloadb.</b></p>

<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_aload</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_aloads</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_aloadb</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.h.</li></ul>
<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_aload</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">) *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">i7_read_word</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">}</span>

<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_aloads</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">) *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">i7_read_sword</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">}</span>

<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_aloadb</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">) *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">i7_read_byte</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">+</span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.c.</li></ul>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. ushiftr, shiftl.</b></p>

<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_shiftl</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_ushiftr</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.h.</li></ul>
<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_shiftl</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">value</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> ((</span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax"> &gt;= </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">) &amp;&amp; (</span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax"> &lt; </span><span class="Extracts-constant-syntax">32</span><span class="Extracts-plain-syntax">)) </span><span class="Extracts-identifier-syntax">value</span><span class="Extracts-plain-syntax"> = (</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax"> &lt;&lt; </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">) *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">value</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">}</span>

<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_ushiftr</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">value</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> ((</span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax"> &gt;= </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">) &amp;&amp; (</span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax"> &lt; </span><span class="Extracts-constant-syntax">32</span><span class="Extracts-plain-syntax">)) </span><span class="Extracts-identifier-syntax">value</span><span class="Extracts-plain-syntax"> = (</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax"> &gt;&gt; </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">) *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">value</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.c.</li></ul>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. jeq, jleu, jnz, jz.</b>These are branch opcodes and return an <span class="extract"><span class="Extracts-extract-syntax">int</span></span>.
</p>

<p class="commentary">The implementation of <span class="extract"><span class="Extracts-extract-syntax">@jleu</span></span> here is modelled on the one from <span class="extract"><span class="Extracts-extract-syntax">dumb-glulxe</span></span>.
Writing code like <span class="extract"><span class="Extracts-extract-syntax">*((i7word_t *) &amp;ux) = x</span></span> really makes you proud to have chosen
C as your programming language, but it works.
</p>

<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">int</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_jeq</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-identifier-syntax">int</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_jleu</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-identifier-syntax">int</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_jnz</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-identifier-syntax">int</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_jz</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.h.</li></ul>
<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">int</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_jeq</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax"> == </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">) </span><span class="Extracts-identifier-syntax">return</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">return</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">}</span>

<span class="Extracts-identifier-syntax">int</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_jleu</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">unsigned_i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">ux</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">uy</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    *((</span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *) &amp;</span><span class="Extracts-identifier-syntax">ux</span><span class="Extracts-plain-syntax">) = </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">; *((</span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *) &amp;</span><span class="Extracts-identifier-syntax">uy</span><span class="Extracts-plain-syntax">) = </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">ux</span><span class="Extracts-plain-syntax"> &lt;= </span><span class="Extracts-identifier-syntax">uy</span><span class="Extracts-plain-syntax">) </span><span class="Extracts-identifier-syntax">return</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">return</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">}</span>

<span class="Extracts-identifier-syntax">int</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_jnz</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax"> != </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">) </span><span class="Extracts-identifier-syntax">return</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">return</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">}</span>

<span class="Extracts-identifier-syntax">int</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_jz</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax"> == </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">) </span><span class="Extracts-identifier-syntax">return</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">return</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.c.</li></ul>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. nop, quit, verify.</b>There is no real meaning for <span class="extract"><span class="Extracts-extract-syntax">@verify</span></span> in this situation: it's supposed to
check the checksum for the contents of a virtual machine, to protect against
the (entirely likely) scenario of a floppy disk sector going bad in 1983.
So we unconditionally store the "okay" result.
</p>

<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_nop</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_quit</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_verify</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.h.</li></ul>
<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_nop</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">}</span>

<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_quit</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">i7_fatal_exit</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">}</span>

<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_verify</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">) *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.c.</li></ul>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. restoreundo, saveundo, hasundo, discardundo.</b>This all works, but we do something pretty inelegant to support <span class="extract"><span class="Extracts-extract-syntax">@restoreundo</span></span>:
we insert a call to a (presumably kit-based) function called <span class="extract"><span class="Extracts-extract-syntax">DealWithUndo</span></span>,
provided this exists. This is done because we are unable safely to follow the
proper Glulx specification. In principle, after a <span class="extract"><span class="Extracts-extract-syntax">@restoreundo</span></span> succeeds,
execution immediately continues from the position in the program where the
<span class="extract"><span class="Extracts-extract-syntax">@saveundo</span></span> occurred. For a while the implementation here imitated this by
using <span class="extract"><span class="Extracts-extract-syntax">longjmp</span></span> and <span class="extract"><span class="Extracts-extract-syntax">setjmp</span></span>, but it all proved very fragile because of the
difficulty of storing <span class="extract"><span class="Extracts-extract-syntax">setjmp</span></span> positions safely in memory.
</p>

<p class="commentary">Correspondingly, our implementation of <span class="extract"><span class="Extracts-extract-syntax">@saveundo</span></span> always stores the result
value 0. The result value 1 would indicate that execution had switched there
from a successful <span class="extract"><span class="Extracts-extract-syntax">@restoreundo</span></span>: but, as noted, that never happens.
</p>

<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_restoreundo</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_saveundo</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_hasundo</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_discardundo</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.h.</li></ul>
<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-plain-syntax">#</span><span class="Extracts-identifier-syntax">ifdef</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_mgl_DealWithUndo</span>
<span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_fn_DealWithUndo</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">#</span><span class="Extracts-identifier-syntax">endif</span>

<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_restoreundo</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">i7_has_snapshot</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">)) {</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">i7_restore_snapshot</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">) *</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">        #</span><span class="Extracts-identifier-syntax">ifdef</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_mgl_DealWithUndo</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">i7_fn_DealWithUndo</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">        #</span><span class="Extracts-identifier-syntax">endif</span>
<span class="Extracts-plain-syntax">    } </span><span class="Extracts-identifier-syntax">else</span><span class="Extracts-plain-syntax"> {</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">) *</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    }</span>
<span class="Extracts-plain-syntax">}</span>

<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_saveundo</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">i7_save_snapshot</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">) *</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">}</span>

<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_hasundo</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">rv</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">; </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">i7_has_snapshot</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">)) </span><span class="Extracts-identifier-syntax">rv</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">) *</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">rv</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">}</span>

<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_discardundo</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">i7_destroy_latest_snapshot</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.c.</li></ul>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. restart, restore, save.</b>For the moment, at least, we intentionally do not implement these. It seems
likely that anyone using C to run interactive fiction is doing so in a wider
framework where saved states will work differently from the traditional model
of asking the user for a filename and then saving data out to a binary file
of that name in the current working directory. Better to do nothing here, and
let users handle this themselves.
</p>

<p class="commentary">Similar considerations apply to <span class="extract"><span class="Extracts-extract-syntax">@restart</span></span>. The intention of this opcode is
essentially to reboot the virtual machine and start over: here, though, we
have a real machine. It's easy enough to reinitialise the process state,
but not so simple to restart execution as if from a clean process start.
</p>

<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_restart</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_restore</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_save</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.h.</li></ul>
<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_restart</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">printf</span><span class="Extracts-plain-syntax">("(</span><span class="Extracts-identifier-syntax">RESTART</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">is</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">not</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">implemented</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">on</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">this</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">C</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">program</span><span class="Extracts-plain-syntax">.)\</span><span class="Extracts-identifier-syntax">n</span><span class="Extracts-plain-syntax">");</span>
<span class="Extracts-plain-syntax">}</span>

<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_restore</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">printf</span><span class="Extracts-plain-syntax">("(</span><span class="Extracts-identifier-syntax">RESTORE</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">is</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">not</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">implemented</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">on</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">this</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">C</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">program</span><span class="Extracts-plain-syntax">.)\</span><span class="Extracts-identifier-syntax">n</span><span class="Extracts-plain-syntax">");</span>
<span class="Extracts-plain-syntax">}</span>

<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_save</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">printf</span><span class="Extracts-plain-syntax">("(</span><span class="Extracts-identifier-syntax">SAVE</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">is</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">not</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">implemented</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">on</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">this</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">C</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">program</span><span class="Extracts-plain-syntax">.)\</span><span class="Extracts-identifier-syntax">n</span><span class="Extracts-plain-syntax">");</span>
<span class="Extracts-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.c.</li></ul>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. streamchar, streamnum, streamunichar.</b></p>

<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_streamnum</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_streamchar</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_streamunichar</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.h.</li></ul>
<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_streamnum</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">i7_print_decimal</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">}</span>

<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_streamchar</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">i7_print_char</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">}</span>

<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_streamunichar</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">i7_print_char</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.c.</li></ul>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. binarysearch.</b>This is a Grand Imperial Hotel among Glulx opcodes, with 8 operands, only the
last of which is a store. It performs a binary search on a block of structures
known to be sorted already. It has a nice general-purpose look but was devised so
that command verbs could be looked up quickly in dictionary tables when interactive
fiction is being played: that's the only use which the standard Inform kits make
of it.
</p>

<p class="commentary">The elegant implementation here comes from Andrew Plotkin's reference code for
<span class="extract"><span class="Extracts-extract-syntax">glulxe</span></span>, a Glulx interpreter. <span class="extract"><span class="Extracts-extract-syntax">options</span></span> is a bitmap of the bits defined below.
In the only use the standard Inform kits make of this opcode, <span class="extract"><span class="Extracts-extract-syntax">options</span></span> will be
just <span class="extract"><span class="Extracts-extract-syntax">serop_KeyIndirect</span></span>, but <span class="extract"><span class="Extracts-extract-syntax">keysize</span></span> will be more than 4, so that the elaborate
speed optimisation for keys of size 1, 2 and 4, and thus <span class="extract"><span class="Extracts-extract-syntax">keybuf</span></span>, are never used.
But we may as well have the full functionality here.
</p>

<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-plain-syntax">#</span><span class="Extracts-identifier-syntax">define</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">serop_KeyIndirect</span><span class="Extracts-plain-syntax">        </span><span class="Extracts-constant-syntax">1</span>
<span class="Extracts-plain-syntax">#</span><span class="Extracts-identifier-syntax">define</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">serop_ZeroKeyTerminates</span><span class="Extracts-plain-syntax">  </span><span class="Extracts-constant-syntax">2</span>
<span class="Extracts-plain-syntax">#</span><span class="Extracts-identifier-syntax">define</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">serop_ReturnIndex</span><span class="Extracts-plain-syntax">        </span><span class="Extracts-constant-syntax">4</span>
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_binarysearch</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">key</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">keysize</span><span class="Extracts-plain-syntax">,</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">start</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">structsize</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">numstructs</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">keyoffset</span><span class="Extracts-plain-syntax">,</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">options</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">s1</span><span class="Extracts-plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.h.</li></ul>
<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_binarysearch</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">key</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">keysize</span><span class="Extracts-plain-syntax">,</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">start</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">structsize</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">numstructs</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">keyoffset</span><span class="Extracts-plain-syntax">,</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">options</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">s1</span><span class="Extracts-plain-syntax">) {</span>

<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">s1</span><span class="Extracts-plain-syntax"> == </span><span class="Extracts-identifier-syntax">NULL</span><span class="Extracts-plain-syntax">) </span><span class="Extracts-identifier-syntax">return</span><span class="Extracts-plain-syntax">; /* </span><span class="Extracts-identifier-syntax">Do</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">not</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">spend</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">any</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">time</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">the</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">result</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">is</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">to</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">be</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">ignored</span><span class="Extracts-plain-syntax"> */</span>


<span class="Extracts-plain-syntax">    /* </span><span class="Extracts-identifier-syntax">If</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">the</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">key</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">size</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">is</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">4</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">or</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">fewer</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">copy</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">it</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">directly</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">into</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">the</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">keybuf</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">array</span><span class="Extracts-plain-syntax"> */</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">unsigned</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">char</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">keybuf</span><span class="Extracts-plain-syntax">[4];</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">options</span><span class="Extracts-plain-syntax"> &amp; </span><span class="Extracts-identifier-syntax">serop_KeyIndirect</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">keysize</span><span class="Extracts-plain-syntax"> &lt;= </span><span class="Extracts-constant-syntax">4</span><span class="Extracts-plain-syntax">)</span>
<span class="Extracts-plain-syntax">            </span><span class="Extracts-identifier-syntax">for</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">int</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">ix</span><span class="Extracts-plain-syntax">=0; </span><span class="Extracts-identifier-syntax">ix</span><span class="Extracts-plain-syntax">&lt;</span><span class="Extracts-identifier-syntax">keysize</span><span class="Extracts-plain-syntax">; </span><span class="Extracts-identifier-syntax">ix</span><span class="Extracts-plain-syntax">++)</span>
<span class="Extracts-plain-syntax">                </span><span class="Extracts-identifier-syntax">keybuf</span><span class="Extracts-plain-syntax">[</span><span class="Extracts-identifier-syntax">ix</span><span class="Extracts-plain-syntax">] = </span><span class="Extracts-identifier-syntax">i7_read_byte</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">key</span><span class="Extracts-plain-syntax"> + </span><span class="Extracts-identifier-syntax">ix</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">    } </span><span class="Extracts-identifier-syntax">else</span><span class="Extracts-plain-syntax"> {</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">switch</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">keysize</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">            </span><span class="Extracts-identifier-syntax">case</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">4</span><span class="Extracts-plain-syntax">:</span>
<span class="Extracts-plain-syntax">                </span><span class="Extracts-identifier-syntax">keybuf</span><span class="Extracts-plain-syntax">[0] = </span><span class="Extracts-identifier-syntax">I7BYTE_0</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">key</span><span class="Extracts-plain-syntax">); </span><span class="Extracts-identifier-syntax">keybuf</span><span class="Extracts-plain-syntax">[1] = </span><span class="Extracts-identifier-syntax">I7BYTE_1</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">key</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">                </span><span class="Extracts-identifier-syntax">keybuf</span><span class="Extracts-plain-syntax">[2] = </span><span class="Extracts-identifier-syntax">I7BYTE_2</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">key</span><span class="Extracts-plain-syntax">); </span><span class="Extracts-identifier-syntax">keybuf</span><span class="Extracts-plain-syntax">[3] = </span><span class="Extracts-identifier-syntax">I7BYTE_3</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">key</span><span class="Extracts-plain-syntax">); </span><span class="Extracts-identifier-syntax">break</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">            </span><span class="Extracts-identifier-syntax">case</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">2</span><span class="Extracts-plain-syntax">:</span>
<span class="Extracts-plain-syntax">                </span><span class="Extracts-identifier-syntax">keybuf</span><span class="Extracts-plain-syntax">[0] = </span><span class="Extracts-identifier-syntax">I7BYTE_0</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">key</span><span class="Extracts-plain-syntax">); </span><span class="Extracts-identifier-syntax">keybuf</span><span class="Extracts-plain-syntax">[1] = </span><span class="Extracts-identifier-syntax">I7BYTE_1</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">key</span><span class="Extracts-plain-syntax">); </span><span class="Extracts-identifier-syntax">break</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">            </span><span class="Extracts-identifier-syntax">case</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax">:</span>
<span class="Extracts-plain-syntax">                </span><span class="Extracts-identifier-syntax">keybuf</span><span class="Extracts-plain-syntax">[0] = </span><span class="Extracts-identifier-syntax">key</span><span class="Extracts-plain-syntax">; </span><span class="Extracts-identifier-syntax">break</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">        }</span>
<span class="Extracts-plain-syntax">    }</span>

<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">bot</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">top</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">numstructs</span><span class="Extracts-plain-syntax">; /* </span><span class="Extracts-identifier-syntax">Initial</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">search</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">range</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">including</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">bot</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">but</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">not</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">top</span><span class="Extracts-plain-syntax"> */</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">while</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">bot</span><span class="Extracts-plain-syntax"> &lt; </span><span class="Extracts-identifier-syntax">top</span><span class="Extracts-plain-syntax">) { /* </span><span class="Extracts-identifier-syntax">I</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">e</span><span class="Extracts-plain-syntax">., </span><span class="Extracts-identifier-syntax">while</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">the</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">search</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">range</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">is</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">not</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">empty</span><span class="Extracts-plain-syntax"> */</span>
<span class="Extracts-plain-syntax">        /* </span><span class="Extracts-identifier-syntax">Find</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">the</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">structure</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">at</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">the</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">midpoint</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">of</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">the</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">search</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">range</span><span class="Extracts-plain-syntax"> */</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">val</span><span class="Extracts-plain-syntax"> = (</span><span class="Extracts-identifier-syntax">top</span><span class="Extracts-plain-syntax">+</span><span class="Extracts-identifier-syntax">bot</span><span class="Extracts-plain-syntax">) / </span><span class="Extracts-constant-syntax">2</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">addr</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">start</span><span class="Extracts-plain-syntax"> + </span><span class="Extracts-identifier-syntax">val</span><span class="Extracts-plain-syntax"> * </span><span class="Extracts-identifier-syntax">structsize</span><span class="Extracts-plain-syntax">;</span>

<span class="Extracts-plain-syntax">        /* </span><span class="Extracts-identifier-syntax">Compute</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">cmp</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">the</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">key</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">matches</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">this</span><span class="Extracts-plain-syntax">, -1 </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">it</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">precedes</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">it</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">follows</span><span class="Extracts-plain-syntax"> */</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">int</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">cmp</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">keysize</span><span class="Extracts-plain-syntax"> &lt;= </span><span class="Extracts-constant-syntax">4</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">            </span><span class="Extracts-identifier-syntax">for</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">int</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">ix</span><span class="Extracts-plain-syntax">=0; (!</span><span class="Extracts-identifier-syntax">cmp</span><span class="Extracts-plain-syntax">) &amp;&amp; </span><span class="Extracts-identifier-syntax">ix</span><span class="Extracts-plain-syntax">&lt;</span><span class="Extracts-identifier-syntax">keysize</span><span class="Extracts-plain-syntax">; </span><span class="Extracts-identifier-syntax">ix</span><span class="Extracts-plain-syntax">++) {</span>
<span class="Extracts-plain-syntax">                </span><span class="Extracts-identifier-syntax">unsigned</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">char</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">byte</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">i7_read_byte</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">addr</span><span class="Extracts-plain-syntax"> + </span><span class="Extracts-identifier-syntax">keyoffset</span><span class="Extracts-plain-syntax"> + </span><span class="Extracts-identifier-syntax">ix</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">                </span><span class="Extracts-identifier-syntax">unsigned</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">char</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">byte2</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">keybuf</span><span class="Extracts-plain-syntax">[</span><span class="Extracts-identifier-syntax">ix</span><span class="Extracts-plain-syntax">];</span>
<span class="Extracts-plain-syntax">                </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">byte</span><span class="Extracts-plain-syntax"> &lt; </span><span class="Extracts-identifier-syntax">byte2</span><span class="Extracts-plain-syntax">) </span><span class="Extracts-identifier-syntax">cmp</span><span class="Extracts-plain-syntax"> = -1;</span>
<span class="Extracts-plain-syntax">                </span><span class="Extracts-identifier-syntax">else</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">byte</span><span class="Extracts-plain-syntax"> &gt; </span><span class="Extracts-identifier-syntax">byte2</span><span class="Extracts-plain-syntax">) </span><span class="Extracts-identifier-syntax">cmp</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">            }</span>
<span class="Extracts-plain-syntax">        } </span><span class="Extracts-identifier-syntax">else</span><span class="Extracts-plain-syntax"> {</span>
<span class="Extracts-plain-syntax">            </span><span class="Extracts-identifier-syntax">for</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">int</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">ix</span><span class="Extracts-plain-syntax">=0; (!</span><span class="Extracts-identifier-syntax">cmp</span><span class="Extracts-plain-syntax">) &amp;&amp; </span><span class="Extracts-identifier-syntax">ix</span><span class="Extracts-plain-syntax">&lt;</span><span class="Extracts-identifier-syntax">keysize</span><span class="Extracts-plain-syntax">; </span><span class="Extracts-identifier-syntax">ix</span><span class="Extracts-plain-syntax">++) {</span>
<span class="Extracts-plain-syntax">                </span><span class="Extracts-identifier-syntax">unsigned</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">char</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">byte</span><span class="Extracts-plain-syntax">  = </span><span class="Extracts-identifier-syntax">i7_read_byte</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">addr</span><span class="Extracts-plain-syntax"> + </span><span class="Extracts-identifier-syntax">keyoffset</span><span class="Extracts-plain-syntax"> + </span><span class="Extracts-identifier-syntax">ix</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">                </span><span class="Extracts-identifier-syntax">unsigned</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">char</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">byte2</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">i7_read_byte</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">key</span><span class="Extracts-plain-syntax"> + </span><span class="Extracts-identifier-syntax">ix</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">                </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">byte</span><span class="Extracts-plain-syntax"> &lt; </span><span class="Extracts-identifier-syntax">byte2</span><span class="Extracts-plain-syntax">) </span><span class="Extracts-identifier-syntax">cmp</span><span class="Extracts-plain-syntax"> = -1;</span>
<span class="Extracts-plain-syntax">                </span><span class="Extracts-identifier-syntax">else</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">byte</span><span class="Extracts-plain-syntax"> &gt; </span><span class="Extracts-identifier-syntax">byte2</span><span class="Extracts-plain-syntax">) </span><span class="Extracts-identifier-syntax">cmp</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">            }</span>
<span class="Extracts-plain-syntax">        }</span>

<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">cmp</span><span class="Extracts-plain-syntax"> == </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">            /* </span><span class="Extracts-identifier-syntax">Success</span><span class="Extracts-plain-syntax">! */</span>
<span class="Extracts-plain-syntax">            </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">options</span><span class="Extracts-plain-syntax"> &amp; </span><span class="Extracts-identifier-syntax">serop_ReturnIndex</span><span class="Extracts-plain-syntax">) *</span><span class="Extracts-identifier-syntax">s1</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">val</span><span class="Extracts-plain-syntax">; </span><span class="Extracts-identifier-syntax">else</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">s1</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">addr</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">            </span><span class="Extracts-identifier-syntax">return</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">        }</span>

<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">cmp</span><span class="Extracts-plain-syntax"> &lt; </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">) </span><span class="Extracts-identifier-syntax">bot</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">val</span><span class="Extracts-plain-syntax">+1; /* </span><span class="Extracts-identifier-syntax">Chop</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">search</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">range</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">to</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">the</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">second</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">half</span><span class="Extracts-plain-syntax"> */</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">else</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">top</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">val</span><span class="Extracts-plain-syntax">; /* </span><span class="Extracts-identifier-syntax">Chop</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">search</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">range</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">to</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">the</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">first</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">half</span><span class="Extracts-plain-syntax"> */</span>
<span class="Extracts-plain-syntax">    }</span>

<span class="Extracts-plain-syntax">    /* </span><span class="Extracts-identifier-syntax">Failure</span><span class="Extracts-plain-syntax">! */</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">options</span><span class="Extracts-plain-syntax"> &amp; </span><span class="Extracts-identifier-syntax">serop_ReturnIndex</span><span class="Extracts-plain-syntax">) *</span><span class="Extracts-identifier-syntax">s1</span><span class="Extracts-plain-syntax"> = -1; </span><span class="Extracts-identifier-syntax">else</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">s1</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.c.</li></ul>
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. mcopy, mzero, malloc, mfree.</b>A Glulx assembly opcode is provided for fast memory copies, which we must
implement. We're choosing not to implement the Glulx <span class="extract"><span class="Extracts-extract-syntax">@malloc</span></span> or <span class="extract"><span class="Extracts-extract-syntax">@mfree</span></span>
opcodes for now, but that will surely need to change in due course. (When that
does change, we will need also to change <span class="extract"><span class="Extracts-extract-syntax">@gestalt</span></span>.)
</p>

<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_mcopy</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_mzero</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_malloc</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_mfree</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.h.</li></ul>
<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_mcopy</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax"> &lt; </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">)</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">for</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">=0; </span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">&lt;</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">; </span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">++)</span>
<span class="Extracts-plain-syntax">            </span><span class="Extracts-identifier-syntax">i7_write_byte</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">+</span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7_read_byte</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">+</span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">));</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">else</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">for</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">=</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">-1; </span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">&gt;=0; </span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">--)</span>
<span class="Extracts-plain-syntax">            </span><span class="Extracts-identifier-syntax">i7_write_byte</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">+</span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7_read_byte</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">+</span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">));</span>
<span class="Extracts-plain-syntax">}</span>

<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_mzero</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">for</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">=0; </span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">&lt;</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">; </span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">++) </span><span class="Extracts-identifier-syntax">i7_write_byte</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">+</span><span class="Extracts-identifier-syntax">i</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">}</span>

<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_malloc</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">printf</span><span class="Extracts-plain-syntax">("</span><span class="Extracts-identifier-syntax">Unimplemented</span><span class="Extracts-plain-syntax">: </span><span class="Extracts-identifier-syntax">i7_opcode_malloc</span><span class="Extracts-plain-syntax">.\</span><span class="Extracts-identifier-syntax">n</span><span class="Extracts-plain-syntax">");</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">i7_fatal_exit</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">}</span>

<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_mfree</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">printf</span><span class="Extracts-plain-syntax">("</span><span class="Extracts-identifier-syntax">Unimplemented</span><span class="Extracts-plain-syntax">: </span><span class="Extracts-identifier-syntax">i7_opcode_mfree</span><span class="Extracts-plain-syntax">.\</span><span class="Extracts-identifier-syntax">n</span><span class="Extracts-plain-syntax">");</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">i7_fatal_exit</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.c.</li></ul>
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>&#167;19. random, setrandom.</b>Note that the <span class="extract"><span class="Extracts-extract-syntax">random(...)</span></span> function built in to Inform is just a name for the
<span class="extract"><span class="Extracts-extract-syntax">@random</span></span> opcode, so we define that here too.
</p>

<p class="commentary">We have no convincing need for a statistically good random number algorithm,
but we do want cross-platform consistency in order that the test suite for Inform
should behave equivalently on MacOS, Linux and Windows &mdash; at least when the
generator is seeded with the same value. To that end, we borrow the algorithm
used by the <span class="extract"><span class="Extracts-extract-syntax">frotz</span></span> Z-machine interpreter, which in turn is based on suggestions
in the Z-machine standards document.
</p>

<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">i7rngseed_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_initial_rng_seed</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_random</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_setrandom</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">s</span><span class="Extracts-plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.h.</li></ul>
<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">i7rngseed_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_initial_rng_seed</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">i7rngseed_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">seed</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">seed</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">A</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">seed</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">interval</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">seed</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">counter</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">return</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">seed</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">}</span>

<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_random</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">uint32_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">rawvalue</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">-&gt;</span><span class="Extracts-identifier-syntax">state</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">seed</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">interval</span><span class="Extracts-plain-syntax"> != </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">rawvalue</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">-&gt;</span><span class="Extracts-identifier-syntax">state</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">seed</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">counter</span><span class="Extracts-plain-syntax">++;</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">-&gt;</span><span class="Extracts-identifier-syntax">state</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">seed</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">counter</span><span class="Extracts-plain-syntax"> == </span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">-&gt;</span><span class="Extracts-identifier-syntax">state</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">seed</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">interval</span><span class="Extracts-plain-syntax">) </span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">-&gt;</span><span class="Extracts-identifier-syntax">state</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">seed</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">counter</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    } </span><span class="Extracts-identifier-syntax">else</span><span class="Extracts-plain-syntax"> {</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">-&gt;</span><span class="Extracts-identifier-syntax">state</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">seed</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">A</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-identifier-syntax">x015a4e35L</span><span class="Extracts-plain-syntax"> * </span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">-&gt;</span><span class="Extracts-identifier-syntax">state</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">seed</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">A</span><span class="Extracts-plain-syntax"> + </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">rawvalue</span><span class="Extracts-plain-syntax"> = (</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">-&gt;</span><span class="Extracts-identifier-syntax">state</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">seed</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">A</span><span class="Extracts-plain-syntax"> &gt;&gt; </span><span class="Extracts-constant-syntax">16</span><span class="Extracts-plain-syntax">) &amp; </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-identifier-syntax">x7fff</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    }</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">uint32_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">value</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax"> == </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">) </span><span class="Extracts-identifier-syntax">value</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">rawvalue</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">else</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax"> &gt;= </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax">) </span><span class="Extracts-identifier-syntax">value</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">rawvalue</span><span class="Extracts-plain-syntax"> % (</span><span class="Extracts-identifier-syntax">uint32_t</span><span class="Extracts-plain-syntax">) (</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">else</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">value</span><span class="Extracts-plain-syntax"> = -(</span><span class="Extracts-identifier-syntax">rawvalue</span><span class="Extracts-plain-syntax"> % (</span><span class="Extracts-identifier-syntax">uint32_t</span><span class="Extracts-plain-syntax">) (-</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">));</span>
<span class="Extracts-plain-syntax">    *</span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax"> = (</span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax">) </span><span class="Extracts-identifier-syntax">value</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">}</span>

<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_setrandom</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">s</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">s</span><span class="Extracts-plain-syntax"> == </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">-&gt;</span><span class="Extracts-identifier-syntax">state</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">seed</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">A</span><span class="Extracts-plain-syntax"> = (</span><span class="Extracts-identifier-syntax">uint32_t</span><span class="Extracts-plain-syntax">) </span><span class="Extracts-identifier-syntax">time</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">NULL</span><span class="Extracts-plain-syntax">);</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">-&gt;</span><span class="Extracts-identifier-syntax">state</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">seed</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">interval</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    } </span><span class="Extracts-identifier-syntax">else</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">s</span><span class="Extracts-plain-syntax"> &lt; </span><span class="Extracts-constant-syntax">1000</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">-&gt;</span><span class="Extracts-identifier-syntax">state</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">seed</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">interval</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">s</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">-&gt;</span><span class="Extracts-identifier-syntax">state</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">seed</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">counter</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    } </span><span class="Extracts-identifier-syntax">else</span><span class="Extracts-plain-syntax"> {</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">-&gt;</span><span class="Extracts-identifier-syntax">state</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">seed</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">A</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">s</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">-&gt;</span><span class="Extracts-identifier-syntax">state</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">seed</span><span class="Extracts-plain-syntax">.</span><span class="Extracts-identifier-syntax">interval</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    }</span>
<span class="Extracts-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.c.</li></ul>
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>&#167;20. setiosys.</b>This opcode in principle allows a story file to select the input-output system
it will use. But the Inform kits only use system 2, called Glk, and this is the
only system we support, so we will simply ignore this.
</p>

<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_setiosys</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.h.</li></ul>
<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_setiosys</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.c.</li></ul>
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>&#167;21. gestalt.</b>This opcode allows a story file to ask the Glulx interpreter running it whether
or not the interpreter can perform certain tasks.
</p>

<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_gestalt</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.h.</li></ul>
<pre class="Extracts-displayed-code all-displayed-code code-font">
<span class="Extracts-identifier-syntax">void</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">i7_opcode_gestalt</span><span class="Extracts-plain-syntax">(</span><span class="Extracts-identifier-syntax">i7process_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">proc</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax">, </span><span class="Extracts-identifier-syntax">i7word_t</span><span class="Extracts-plain-syntax"> *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">int</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">r</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">switch</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">x</span><span class="Extracts-plain-syntax">) {</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">case</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">: </span><span class="Extracts-identifier-syntax">r</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-identifier-syntax">x00030103</span><span class="Extracts-plain-syntax">; </span><span class="Extracts-identifier-syntax">break</span><span class="Extracts-plain-syntax">; /* </span><span class="Extracts-identifier-syntax">Say</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">that</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">the</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">Glulx</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">version</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">is</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">v3</span><span class="Extracts-plain-syntax">.1.3 */</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">case</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax">: </span><span class="Extracts-identifier-syntax">r</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax">;          </span><span class="Extracts-identifier-syntax">break</span><span class="Extracts-plain-syntax">; /* </span><span class="Extracts-identifier-syntax">Say</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">that</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">the</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">interpreter</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">version</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">is</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax"> */</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">case</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">2</span><span class="Extracts-plain-syntax">: </span><span class="Extracts-identifier-syntax">r</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;          </span><span class="Extracts-identifier-syntax">break</span><span class="Extracts-plain-syntax">; /* </span><span class="Extracts-identifier-syntax">We</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">do</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">not</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">yet</span><span class="Extracts-plain-syntax">) </span><span class="Extracts-identifier-syntax">support</span><span class="Extracts-plain-syntax"> @</span><span class="Extracts-identifier-syntax">setmemsize</span><span class="Extracts-plain-syntax"> */</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">case</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">3</span><span class="Extracts-plain-syntax">: </span><span class="Extracts-identifier-syntax">r</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax">;          </span><span class="Extracts-identifier-syntax">break</span><span class="Extracts-plain-syntax">; /* </span><span class="Extracts-identifier-syntax">We</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">do</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">support</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">UNDO</span><span class="Extracts-plain-syntax"> */</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">case</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">4</span><span class="Extracts-plain-syntax">: </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">y</span><span class="Extracts-plain-syntax"> == </span><span class="Extracts-constant-syntax">2</span><span class="Extracts-plain-syntax">) </span><span class="Extracts-identifier-syntax">r</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax">;     /* </span><span class="Extracts-identifier-syntax">We</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">do</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">support</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">Glk</span><span class="Extracts-plain-syntax"> */</span>
<span class="Extracts-plain-syntax">                       </span><span class="Extracts-identifier-syntax">else</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">r</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;     /* </span><span class="Extracts-identifier-syntax">But</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">not</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">any</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">other</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">I</span><span class="Extracts-plain-syntax">/</span><span class="Extracts-identifier-syntax">O</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">system</span><span class="Extracts-plain-syntax"> */</span>
<span class="Extracts-plain-syntax">                </span><span class="Extracts-identifier-syntax">break</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">case</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">5</span><span class="Extracts-plain-syntax">: </span><span class="Extracts-identifier-syntax">r</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax">;          </span><span class="Extracts-identifier-syntax">break</span><span class="Extracts-plain-syntax">; /* </span><span class="Extracts-identifier-syntax">We</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">do</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">support</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">Unicode</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">operations</span><span class="Extracts-plain-syntax"> */</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">case</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">6</span><span class="Extracts-plain-syntax">: </span><span class="Extracts-identifier-syntax">r</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax">;          </span><span class="Extracts-identifier-syntax">break</span><span class="Extracts-plain-syntax">; /* </span><span class="Extracts-identifier-syntax">We</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">do</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">support</span><span class="Extracts-plain-syntax"> @</span><span class="Extracts-identifier-syntax">mzero</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">and</span><span class="Extracts-plain-syntax"> @</span><span class="Extracts-identifier-syntax">mcopy</span><span class="Extracts-plain-syntax"> */</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">case</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">7</span><span class="Extracts-plain-syntax">: </span><span class="Extracts-identifier-syntax">r</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;          </span><span class="Extracts-identifier-syntax">break</span><span class="Extracts-plain-syntax">; /* </span><span class="Extracts-identifier-syntax">We</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">do</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">not</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">yet</span><span class="Extracts-plain-syntax">) </span><span class="Extracts-identifier-syntax">support</span><span class="Extracts-plain-syntax"> @</span><span class="Extracts-identifier-syntax">malloc</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">or</span><span class="Extracts-plain-syntax"> @</span><span class="Extracts-identifier-syntax">mfree</span><span class="Extracts-plain-syntax"> */</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">case</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">8</span><span class="Extracts-plain-syntax">: </span><span class="Extracts-identifier-syntax">r</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;          </span><span class="Extracts-identifier-syntax">break</span><span class="Extracts-plain-syntax">; /* </span><span class="Extracts-identifier-syntax">Since</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">we</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">do</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">not</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">support</span><span class="Extracts-plain-syntax"> @</span><span class="Extracts-identifier-syntax">malloc</span><span class="Extracts-plain-syntax"> */</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">case</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">9</span><span class="Extracts-plain-syntax">: </span><span class="Extracts-identifier-syntax">r</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;          </span><span class="Extracts-identifier-syntax">break</span><span class="Extracts-plain-syntax">; /* </span><span class="Extracts-identifier-syntax">We</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">do</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">not</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">support</span><span class="Extracts-plain-syntax"> @</span><span class="Extracts-identifier-syntax">accelfunc</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">pr</span><span class="Extracts-plain-syntax"> @</span><span class="Extracts-identifier-syntax">accelparam</span><span class="Extracts-plain-syntax"> */</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">case</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">10</span><span class="Extracts-plain-syntax">: </span><span class="Extracts-identifier-syntax">r</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">0</span><span class="Extracts-plain-syntax">;         </span><span class="Extracts-identifier-syntax">break</span><span class="Extracts-plain-syntax">; /* </span><span class="Extracts-identifier-syntax">And</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">therefore</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">provide</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">none</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">of</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">their</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">accelerants</span><span class="Extracts-plain-syntax"> */</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">case</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">11</span><span class="Extracts-plain-syntax">: </span><span class="Extracts-identifier-syntax">r</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax">;         </span><span class="Extracts-identifier-syntax">break</span><span class="Extracts-plain-syntax">; /* </span><span class="Extracts-identifier-syntax">We</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">do</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">support</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">floating</span><span class="Extracts-plain-syntax">-</span><span class="Extracts-identifier-syntax">point</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">maths</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">operations</span><span class="Extracts-plain-syntax"> */</span>
<span class="Extracts-plain-syntax">        </span><span class="Extracts-identifier-syntax">case</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-constant-syntax">12</span><span class="Extracts-plain-syntax">: </span><span class="Extracts-identifier-syntax">r</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-constant-syntax">1</span><span class="Extracts-plain-syntax">;         </span><span class="Extracts-identifier-syntax">break</span><span class="Extracts-plain-syntax">; /* </span><span class="Extracts-identifier-syntax">We</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">do</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">support</span><span class="Extracts-plain-syntax"> @</span><span class="Extracts-identifier-syntax">hasundo</span><span class="Extracts-plain-syntax"> </span><span class="Extracts-identifier-syntax">and</span><span class="Extracts-plain-syntax"> @</span><span class="Extracts-identifier-syntax">discardundo</span><span class="Extracts-plain-syntax"> */</span>
<span class="Extracts-plain-syntax">    }</span>
<span class="Extracts-plain-syntax">    </span><span class="Extracts-identifier-syntax">if</span><span class="Extracts-plain-syntax"> (</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax">) *</span><span class="Extracts-identifier-syntax">z</span><span class="Extracts-plain-syntax"> = </span><span class="Extracts-identifier-syntax">r</span><span class="Extracts-plain-syntax">;</span>
<span class="Extracts-plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This is part of the extract file inform7_clib.c.</li></ul>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="5-cmm.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-cg.html">2</a></li><li class="progresschapter"><a href="3-fti.html">3</a></li><li class="progresschapter"><a href="4-fi6.html">4</a></li><li class="progresscurrentchapter">5</li><li class="progresssection"><a href="5-fnc.html">fnc</a></li><li class="progresssection"><a href="5-cnm.html">cnm</a></li><li class="progresssection"><a href="5-crf.html">crf</a></li><li class="progresssection"><a href="5-cgv.html">cgv</a></li><li class="progresssection"><a href="5-cmm.html">cmm</a></li><li class="progresscurrent">cas</li><li class="progresssection"><a href="5-car.html">car</a></li><li class="progresssection"><a href="5-cpc.html">cpc</a></li><li class="progresssection"><a href="5-ccn.html">ccn</a></li><li class="progresssection"><a href="5-clt.html">clt</a></li><li class="progresssection"><a href="5-com.html">com</a></li><li class="progresssection"><a href="5-cfm.html">cfm</a></li><li class="progresssection"><a href="5-cim.html">cim</a></li><li class="progresssection"><a href="5-cmn.html">cmn</a></li><li class="progresssection"><a href="5-cuf.html">cuf</a></li><li class="progressnext"><a href="5-car.html">&#10095;</a></li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

